// 资源加载模块

// PerfabsBundle: null,
// PerfabsinoutBundle: null,
// AtlasBundle: null,
// OpeningBundle
// NoteBundle

let bgData = {};
let atlasData = {};
let resources = {};
let uuids = {};

let fontAtlas = {};

window.Loader = {
    /**
     * 加载JSON
     * @param filePath 文件路径
     * @param callback 回调函数
     */
    loadJson (filePath, callback) {
        cc.resources.load(filePath, cc.JsonAsset, (err, data) => {
            if (err) return cc.warn(`loadJson Error: `, filePath);
            callback && callback(JSON.parse(JSON.stringify(data)).json);

            // 用完释放资源
            Loader.onReleaseAssets([ data ]);
        });
    },

    // 加载音符JSON
    loadNoteJson (filePath, callback) {
        if (filePath.includes('NOTE/')) {
            filePath = filePath.substring(5, 99);
        }

        let bundle = _BundleManager.NOTEBundle;
        bundle.load(filePath, cc.JsonAsset, (err, data) => {
            if (err) return cc.warn(`loadNoteJson Error: `, filePath);
            let _jsonData = JSON.parse(JSON.stringify(data)).json;
            callback && callback(_jsonData);

            // 用完释放资源
            Loader.onReleaseAssets([ data ]);
        })
    },

    /**
     * 通过名字加载预制体
     * @param names 预制体数组
     * @param pregressCallback 加载进度
     * @param completeCallback 加载完成回调
     */
    loadPrefab: (names, pregressCallback, completeCallback) => {
        let urls = [];
        names.forEach(item => urls.push(Names[item]));
        Loader.loadPrefabByUrls(urls, pregressCallback, completeCallback);
    },

    /**
     * 通过路径加载预制体
     * @param names 预制体数组
     * @param pregressCallback 加载进度
     * @param completeCallback 加载完成回调
     */
    loadPrefabByUrls (urls, pregressCallback, completeCallback) {
        let bundle = _BundleManager.PerfabsBundle;
        // cc.log('bundle ==', bundle);
        bundle.load(urls, pregressCallback, (err, assets) => {
            if (err) return cc.error(`加载资源组失败：${urls}, error:${err}`);
            assets.forEach((item, index) => {
                // resources[urls[index]] = item;
                uuids[urls[index]] = item._uuid;
            })
            completeCallback(assets);
        })
    },

    getAsset (_uuid) {
        let asset = cc.assetManager.assets._map[_uuid];
        // cc.log('asset =>', asset);
        return asset;
    },

    // 释放资源
    onReleaseAssets (assets) {
        if (!assets) return;
        assets.forEach( asset => {
            if (!asset) return;
            // cc.log('decRef ==>', asset._name, asset._ref, asset._uuid);
            asset.decRef && asset.decRef();
            if (asset._ref == 0) asset = null;
        })
    },
    

    /**
     * 获取预制体节点
     * @param name 预制体名字
     * @returns 返回节点
     */
    getInstantiate(name, isCheck) {
        let url = Names[name];
        let _uuid = uuids[url];
        if (!_uuid) return !isCheck && cc.error(`${url}资源还未加载`, name);
        if (!this.getAsset(_uuid)) return;
        return cc.instantiate(this.getAsset(_uuid));
    },
    // getInstantiate(name) {
    //     let url = Names[name];
    //     if (!resources[url]) return cc.error(`${url}资源还未加载`);
    //     return cc.instantiate(resources[url]);
    // },

    /**
     * 加载图片
     * @param imgSpr 图片
     * @param path  图集路径
     * @param imgName 图片名
     * @param cb 回调函数
     * @param imgBox 图片适配盒子
     */
    loadImg(imgSpr, path, imgName, cb, imgBox) {
        if (atlasData[path]) {
            let spriteFrame = this.getAsset(atlasData[path]).getSpriteFrame(imgName);
            imgSpr.spriteFrame = spriteFrame;
            imgSpr.addAutoReleaseAsset(spriteFrame);
            // cc.log('imgName =', imgName, atlas.getSpriteFrame(imgName));
            imgBox && this.setSpriteNode(imgBox, spriteFrame);
            return cb && cb(spriteFrame);
        }
        
        let bundle = _BundleManager.AtlasBundle;
        bundle.load(path, cc.SpriteAtlas, (err, atlas) => {
            if (err) return cc.error(`图集：${path}中图片：${imgName}加载失败！！！`);
            if (!imgSpr) return;
            // atlasData[path] = atlas._uuid;
            try {
                let spriteFrame = atlas.getSpriteFrame(imgName);
                imgSpr.spriteFrame = spriteFrame
                // cc.log('imgName =', path, imgName, atlas.getSpriteFrame(imgName));
                imgBox && this.setSpriteNode(imgBox, spriteFrame);
                cb && cb(spriteFrame, atlas);

                imgSpr.addAutoReleaseAsset(atlas);
                imgSpr.addAutoReleaseAsset(spriteFrame);
            } catch (e) {

            }
        });
    },

    preloadAtlas (path, cb) {
        if (!path) return cc.warn('preloadAtlas 未传参数');
        let bundle = _BundleManager.AtlasBundle;
        bundle.load(path, cc.SpriteAtlas, (err, atlas) => {
            if (err) return cc.error(`图集：${path}加载失败！！！`);
            atlas.addRef && atlas.addRef();
            // cc.log('atlas >>', path, atlas);
            cb && cb(atlas);
        });
    },

    /**
     * 设置图片适配父节点
     * @param imgBox 父节点
     * @param spriteFrame 
     */
    setSpriteNode (imgBox, spriteFrame, isSpecial) {
        _PublicMethods.setspritesizeinnodes(imgBox, spriteFrame, isSpecial);
    },

    /**
     * 加载背景图片(非图集)
     * @param imgSpr 图片精灵
     * @param path 图片路径
     * @param cb 回调函数
     * @returns 
     */
    loadBgImg (imgSpr, path, imgName, cb) {
        path += `/${imgName}`;
        // cc.warn('loadBgImg =', path);
        if (bgData[path]) {
            let spriteFrame = this.getAsset(bgData[path]);
            imgSpr.spriteFrame = spriteFrame;
            return cb && cb(spriteFrame);
        }

        let bundle = _BundleManager.AtlasBundle;
        bundle.load(path, cc.SpriteFrame, (err, spriteFrame) => {
            if (err) return cc.error(`图片：${path}加载失败！！！`);
            // bgData[path] = spriteFrame._uuid;
            cb && cb(spriteFrame);
            
            if ( !imgSpr ) return;
            imgSpr.spriteFrame = spriteFrame;
            try {
                imgSpr.addAutoReleaseAsset(spriteFrame);
            } catch (e) {
                
            }
        })
    },

    preloadBgImg ( path, imgName, cb ) {
        path += `/${imgName}`;
        let bundle = _BundleManager.AtlasBundle;
        bundle.load(path, cc.SpriteFrame, (err, spriteFrame) => {
            if ( err ) return;
            
            spriteFrame.addRef && spriteFrame.addRef();
            cb && cb(spriteFrame);
        })
    },

    /**
     * 添加节点
     * @param prefab 预制体
     * @param parentNode 父节点
     * @param position 坐标
     * @param zIndex 图层
     * @returns 返回新节点
     */
    loadNode(prefab, parentNode, position = cc.v2(0, 0), zIndex = 0) {
        // if (resources[Names[prefab]]) prefab = resources[Names[prefab]];
        if (typeof(prefab) == 'string') prefab = this.getInstantiate(prefab);
        // cc.log('loadNode ==>', prefab, parentNode, position, zIndex)
        if (!prefab || !cc.isValid(prefab)) return;
        let newNode = cc.instantiate(prefab);
        if (!newNode) return;
        newNode.position = position;
        newNode.zIndex = zIndex;
        parentNode.addChild(newNode);
        return newNode;
    },

    /**
     * 加载节点通用
     * @param { prefabName, nodePos, parentNode, zIndex, data, cb } options 预制体名字，坐标，父节点, 层级，数据，回调函数
     */
    loadNodeCommon (options = { prefabName, nodePos, parentNode, zIndex, data, cb }) {
        cc.game.emit('loadPrefab', options);
    },

    /**
     * 加载CSV文件
     * @param fileName 文件名
     * @param cb 回调函数
     */
    loadCSV(fileName, cb) {
        let csvHelpers = new CSVHelper();
        csvHelpers.loadCsv(`CSV/${fileName}`, cb);
    },

    // 龙骨换肤
    loadDragonRes(tex, ske, dragon, armatureName = 'default') {
        // cc.log('tex_ske: ', tex, ske, armatureName);
        let basePath = `Animation/Guest/KR/`;
        let texPath = basePath + tex;
        let skePath = basePath + ske;
        let bundle = _BundleManager.PerfabsBundle;
        bundle.load(texPath, dragonBones.DragonBonesAtlasAsset, null, (err, atlasasset) => {
            if (err) return cc.error('tex err: ', err);
            if (dragon) dragon.dragonAtlasAsset = atlasasset
            bundle.load(skePath, dragonBones.DragonBonesAsset, null, (err, asset) => {
                if (err) return cc.error('ske err: ', err);
                if (dragon) dragon.dragonAsset = asset;
                if (dragon) dragon.armatureName = armatureName;
            });
        });
    },

    // 加载spine资源
    loadSpineRes (spinePath = `Spine/singer/CLAIRE`, skeleton, cb) {
        let _isNPC = spinePath.includes('/NPC');
        let bundle = _isNPC ? _BundleManager.PerfabsBundle : _BundleManager.AtlasBundle;
        bundle.load(spinePath, sp.SkeletonData, (err, skeletonData) => {
            if (err) return cc.error(err);
            try {
                if (skeleton) {
                    skeleton.skeletonData = skeletonData;
                    skeleton.addAutoReleaseAsset(skeletonData);
                } else {
                    skeletonData.addRef && skeletonData.addRef();
                }
                cb && cb(skeletonData);
            } catch (e) {
                cc.error('loadSpineRes error: ', e.stack);
            }
        });
    },

    /**
     * 加载文本字体
     * @param fileName 字体文件名
     * @param text 文本组件
     */
    loadFont (fileName, text) {
        if (fontAtlas[fileName]) return Loader.setFont(text, fileName);

        let bundle = _BundleManager.migrationBundle;
        if (!bundle) return;
        bundle.load(fileName, cc.Font, (err, font) => {
            if (err) return cc.error('loadFont err: ', err);
            fontAtlas[fileName] = font;
            Loader.setFont(text, fileName);
        });
    },

    /**
     * 设置字体
     * @param text 文本组件
     */
    setFont (text, fileName) {
        text.font = fontAtlas[fileName];
    },
}
